using LiJ.Common.Core;
using LiJ.Common.Core.Enums;
using LiJ.Common.Extention;
using LiJ.Http.Extention;
using LiJ.Http.Mos;
using LiJ.Pay.WeiXin.Pay.Mos;
using LiJ.Pay.WeiXin.SysTools;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;

namespace LiJ.Pay.WeiXin.Pay
{
	/// <summary>
	///  发起支付相关API
	/// </summary>
	public class WxPayTradeApi : WxPayBaseApi
	{
		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="config">配置信息，如果这里为空，请在程序入口处 设置WxPayBaseApi.DefaultConfig的值</param>
		public WxPayTradeApi(WxPayCenterConfig config = null)
			: base(config)
		{
		}

		/// <summary>
		///   统一下单接口
		/// </summary>
		/// <param name="order"></param>
		/// <returns></returns>
		public async Task<WxAddPayOrderResp> AddUniOrderAsync(WxAddPayUniOrderReq order)
		{
			if (string.IsNullOrEmpty(order.notify_url))
			{
				order.notify_url = base.ApiConfig.NotifyUrl;
			}
			SortedDictionary<string, object> dics = order.GetDics();
			string addressUrl = "https://api.mch.weixin.qq.com" + "/pay/unifiedorder";
			return await base.PostApiAsync(addressUrl, dics, (Func<HttpResponseMessage, Task<WxAddPayOrderResp>>)null, (HttpClient)null, (Action<SortedDictionary<string, object>>)null);
		}

		/// <summary>
		///   刷卡下单接口
		/// 提交支付请求后微信会同步返回支付结果。当返回结果为“系统错误（err_code=SYSTEMERROR）”时，商户系统等待5秒后调用【查询订单API】，查询支付实际交易结果；
		/// 当返回结果为“USERPAYING”时，商户系统可设置间隔时间(建议10秒)重新查询支付结果，直到支付成功或超时(建议30秒)
		/// </summary>
		/// <param name="order"></param>
		/// <returns></returns>
		public async Task<WxAddMicroPayOrderResp> AddMicroPayOrderAsync(WxAddMicroPayOrderReq order)
		{
			SortedDictionary<string, object> dics = order.GetDics();
			string addressUrl = "https://api.mch.weixin.qq.com" + "/pay/micropay";
			return await base.PostApiAsync(addressUrl, dics, (Func<HttpResponseMessage, Task<WxAddMicroPayOrderResp>>)null, (HttpClient)null, (Action<SortedDictionary<string, object>>)null);
		}

		/// <summary>
		///  获取js和小程序唤起客户端参数
		/// </summary>
		/// <param name="prepayId">预支付交易Id</param>
		/// <returns></returns>
		public WxGetJsClientParaResp GetJsClientParaResp(string prepayId)
		{
			WxGetJsClientParaResp wxGetJsClientParaResp = new WxGetJsClientParaResp
			{
				app_id = base.ApiConfig.AppId,
				time_stamp = DateTime.Now.ToLocalSeconds().ToString(),
				nonce = SysUtil.GenerateNonceStr(),
				package = "prepay_id=" + prepayId
			};
			SortedDictionary<string, object> xmlDirs = new SortedDictionary<string, object>
			{
				["appId"] = wxGetJsClientParaResp.app_id,
				["timeStamp"] = wxGetJsClientParaResp.time_stamp,
				["nonceStr"] = wxGetJsClientParaResp.nonce,
				["package"] = wxGetJsClientParaResp.package,
				["signType"] = wxGetJsClientParaResp.sign_type
			};
			wxGetJsClientParaResp.sign = base.GetSign(WxPayBaseApi.GetSignContent(xmlDirs));
			return wxGetJsClientParaResp;
		}

		/// <summary>
		/// 获取app唤起客户端参数
		/// </summary>
		/// <param name="prepayId">预支付交易Id</param>
		/// <returns></returns>
		public WxGetAppClientParaResp GetAppClientParaResp(string prepayId)
		{
			WxGetAppClientParaResp wxGetAppClientParaResp = new WxGetAppClientParaResp
			{
				app_id = base.ApiConfig.AppId,
				mch_id = base.ApiConfig.MchId,
				time_stamp = DateTime.Now.ToLocalSeconds().ToString(),
				nonce = SysUtil.GenerateNonceStr(),
				prepay_id = prepayId,
				package = "Sign=WXPay"
			};
			SortedDictionary<string, object> xmlDirs = new SortedDictionary<string, object>
			{
				["appid"] = wxGetAppClientParaResp.app_id,
				["partnerid"] = wxGetAppClientParaResp.mch_id,
				["timestamp"] = wxGetAppClientParaResp.time_stamp,
				["noncestr"] = wxGetAppClientParaResp.nonce,
				["package"] = wxGetAppClientParaResp.package,
				["prepayid"] = wxGetAppClientParaResp.prepay_id
			};
			wxGetAppClientParaResp.sign = base.GetSign(WxPayBaseApi.GetSignContent(xmlDirs));
			return wxGetAppClientParaResp;
		}

		/// <summary>
		///  查询订单接口
		/// </summary>
		/// <param name="transaction_id">微信订单号 二选一 String(32) 微信的订单号，建议优先使用</param>
		/// <param name="out_trade_no"> 商户订单号 String(32)</param>
		/// <returns></returns>
		public async Task<WxPayQueryOrderResp> QueryOrderAsync(string transaction_id, string out_trade_no)
		{
			string addressUrl = "https://api.mch.weixin.qq.com" + "/pay/orderquery";
			SortedDictionary<string, object> xmlDirs = new SortedDictionary<string, object>
			{
				["nonce_str"] = Guid.NewGuid().ToString().Replace("-", ""),
				["out_trade_no"] = out_trade_no,
				["transaction_id"] = transaction_id
			};
			return await base.PostApiAsync(addressUrl, xmlDirs, (Func<HttpResponseMessage, Task<WxPayQueryOrderResp>>)null, (HttpClient)null, (Action<SortedDictionary<string, object>>)null);
		}

		/// <summary>
		///  订单通知结果解析，并完成验证
		/// </summary>
		/// <param name="contentXmlStr">通知结果内容</param>
		/// <returns>如果签名验证不通过，Ret=310</returns>
		public WxPayOrderTradeResp DecryptPayResult(string contentXmlStr)
		{
			return base.GetRespResult<WxPayOrderTradeResp>(contentXmlStr);
		}

		/// <summary>
		///  转换短链api
		/// </summary>
		/// <param name="long_url"></param>
		/// <returns></returns>
		public async Task<WxPayGetShortUrlResp> GetShortUrlAsync(string long_url)
		{
			string addressUrl = "https://api.mch.weixin.qq.com" + "/tools/shorturl";
			SortedDictionary<string, object> xmlDirs = new SortedDictionary<string, object>
			{
				["nonce_str"] = SysUtil.GenerateNonceStr(),
				["long_url"] = long_url
			};
			return await base.PostApiAsync(addressUrl, xmlDirs, (Func<HttpResponseMessage, Task<WxPayGetShortUrlResp>>)null, (HttpClient)null, (Action<SortedDictionary<string, object>>)delegate(SortedDictionary<string, object> d)
			{
				d["long_url"] = d["long_url"].UrlEncode();
			});
		}

		/// <summary>
		///  授权码查询OPENID接口
		/// </summary>
		/// <param name="auth_code"></param>
		/// <returns></returns>
		public async Task<WxPayAuthCodeOpenIdResp> GetAuthCodeOpenIdAsync(string auth_code)
		{
			string addressUrl = "https://api.mch.weixin.qq.com" + "/tools/authcodetoopenid";
			SortedDictionary<string, object> xmlDirs = new SortedDictionary<string, object>
			{
				["nonce_str"] = SysUtil.GenerateNonceStr(),
				["auth_code"] = auth_code
			};
			return await base.PostApiAsync(addressUrl, xmlDirs, (Func<HttpResponseMessage, Task<WxPayAuthCodeOpenIdResp>>)null, (HttpClient)null, (Action<SortedDictionary<string, object>>)null);
		}

		/// <summary>
		/// 生成二维码地址(扫码支付模式一)
		/// </summary>
		/// <param name="product_id"></param>
		/// <returns></returns>
		public string CreateScanCode(string product_id)
		{
			string signContent = WxPayBaseApi.GetSignContent(new SortedDictionary<string, object>
			{
				["time_stamp"] = DateTime.Now.ToLocalSeconds().ToString(),
				["nonce_str"] = SysUtil.GenerateNonceStr(),
				["product_id"] = product_id,
				["appid"] = base.ApiConfig.AppId,
				["mch_id"] = base.ApiConfig.MchId
			});
			string sign = base.GetSign(signContent);
			return "weixin://wxpay/bizpayurl?" + signContent + "&sign=" + sign;
		}

		/// <summary>
		/// 解析微信扫码回调消息实体（模式一）
		/// </summary>
		/// <param name="contentStr">消息实体</param>
		/// <returns></returns>
		public WxPayScanCallBackMo DecryptScanCallBackMsg(string contentStr)
		{
			return base.GetRespResult<WxPayScanCallBackMo>(contentStr);
		}

		/// <summary>
		///  把统一下单结果响应给微信支付系统
		/// </summary>
		/// <param name="uniOrder"></param>
		/// <returns></returns>
		public string GetScanCallBackResponse(WxAddPayOrderResp uniOrder)
		{
			SortedDictionary<string, object> dics = new WxPayScanCallBackResMo
			{
				err_code_des = uniOrder.err_code_des,
				prepay_id = uniOrder.prepay_id,
				result_code = uniOrder.result_code,
				return_code = uniOrder.return_code,
				return_msg = uniOrder.return_msg
			}.GetDics();
			dics.Add("appid", base.ApiConfig.AppId);
			dics.Add("mch_id", base.ApiConfig.MchId);
			base.CompleteDicSign(dics);
			return dics.ProduceXml();
		}

		/// <summary>
		/// 下载对账单
		/// </summary>
		/// <param name="billReq"></param>
		/// <returns></returns>
		public async Task<ResultMo<string>> DownloadBillAsync(WxPayDownloadBillReq billReq)
		{
			SortedDictionary<string, object> dics = billReq.GetDics();
			dics.Add("appid", base.ApiConfig.AppId);
			dics.Add("mch_id", base.ApiConfig.MchId);
			base.CompleteDicSign(dics);
			HttpResponseMessage httpResponseMessage = await new LHttpRequest
			{
				HttpMothed = HttpMothed.Post,
				AddressUrl = "https://api.mch.weixin.qq.com" + "/pay/downloadbill",
				CustomBody = dics.ProduceXml()
			}.RestSend(null);
			if (!httpResponseMessage.IsSuccessStatusCode)
			{
				return new ResultMo<string>
				{
					Ret = -1,
					Msg = "当前请求出错！"
				};
			}
			string text = await httpResponseMessage.Content.ReadAsStringAsync();
			return text.StartsWith("<xml>") ? new ResultMo<string>(text) : new ResultMo<string>(ResultTypes.ObjectStateError, text);
		}
	}
}
